extends Node2D

signal progress_made

const MAX_LEVEL = 5

@export var vehicle_scene: PackedScene
@export var coin_scene: PackedScene
@export var decoration_scene: PackedScene

var _score: int = 0
var _coins: int = 0
var _level: int = 0

@onready var vehicles_container: Node2D = $VehiclesContainer
@onready var decorations_container: Node2D = $DecorationsContainer
@onready var coins_container: Node2D = $CoinsContainer
@onready var spawn_point: Marker2D = $SpawnerPoint
@onready var score_label: Label = $UI/ScoreLabel
@onready var coins_label: Label = $UI/Coins/CoinsLabel
@onready var game_over: Control = $UI/GameOver
@onready var spawner_timer: Timer = $Timers/SpawnerTimer
@onready var die_audio: AudioStreamPlayer = $Audio/DieAudio
@onready var collect_coin_audio: AudioStreamPlayer = $Audio/CollectCoinAudio


func _on_score_timer_timeout() -> void:
	_score += 1
	score_label.text = str(_score)


func _on_spawner_timer_timeout() -> void:
	_spawn()


func _spawn() -> void:
	var random: int = randi_range(0, 2)
	
	if random <= 1:
		_spawn_vehicle()
	elif random == 2:
		_spawn_coin()

func _spawn_vehicle() -> void:
	var vehicle_instance: Area2D = vehicle_scene.instantiate()
	vehicles_container.add_child(vehicle_instance)
	
	vehicle_instance.position = spawn_point.position
	
	vehicle_instance.body_entered.connect(_on_vehicle_body_entered.bind(vehicle_instance))
	progress_made.connect(vehicle_instance._on_parent_progress_made)
	
	
func _on_vehicle_body_entered(body: Node2D, vehicle: Area2D) -> void:
	if body.is_in_group("player"):
		vehicle.disable_particles()
		die_audio.play()
		
		game_over.show()
		get_tree().paused = true


func _spawn_coin() -> void:
	var coin_instance: Area2D = coin_scene.instantiate()
	coins_container.add_child(coin_instance)
	
	coin_instance.position = spawn_point.position 
	coin_instance.body_entered.connect(_on_coin_body_entered.bind(coin_instance))


func _on_coin_body_entered(body: Node2D, coin: Area2D) -> void:
	if body.is_in_group("player"):
		_coins += 1
		coins_label.text = str(_coins)
		
		coin.collect_coin()
		
		collect_coin_audio.play()


func _on_progression_timer_timeout() -> void:
	_level +=  1
	if _level >= MAX_LEVEL:
		return
	
	var progression_amount: float = 1.15
	Global.speed *= progression_amount 
	spawner_timer.wait_time /= progression_amount
	
	progress_made.emit();


func _on_decoration_timer_timeout() -> void:
	var decoration_instantiate: Area2D = decoration_scene.instantiate()
	decorations_container.add_child(decoration_instantiate)
	
	decoration_instantiate.position = spawn_point.position 
	const y_offset: float = 40.0
	decoration_instantiate.position.y -= y_offset  
